package services

import (
	"errors"
	"fmt"
	global2 "longmen/server/config/global"
	_const "longmen/server/pkg/common/helper/const"
	"longmen/server/pkg/common/helper/encrypt"
	time2 "longmen/server/pkg/common/helper/timehelper"
	"longmen/server/pkg/common/helper/util"
	"longmen/server/pkg/db/mysql"
	"longmen/server/pkg/db/mysql/db_live"
	"longmen/server/pkg/db/mysql/db_main"
	"longmen/server/pkg/db/mysql/models/models_live"
	"longmen/server/pkg/db/mysql/models/models_main"
	"longmen/server/pkg/db/redis/cache"
	"time"

	"github.com/spf13/cast"

	"gorm.io/gorm"

	"longmen/server/pkg/common/api_models"

	"github.com/jinzhu/copier"
	"github.com/labstack/echo/v4"
)

func (s *Service) GetUserById(uid int) (*models_main.User, error) {
	fName := "GetUserById"
	result, err := mysql.GetUserParam(map[string]interface{}{"id": uid})
	if err != nil {
		return nil, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	return result, nil
}

func (s *Service) GetUser(param map[string]interface{}) (*models_main.User, error) {
	return mysql.GetUserParam(param)
}

func (s *Service) GetUserAuth(uid int) (*models_main.UserAuth, error) {
	fName := "GetUserById"
	auth, err := db_main.GetUserAuthParam(map[string]interface{}{"uid": uid})
	if err != nil {
		return nil, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	return auth, nil
}

func (s *Service) GetUserAddress(uid int) (*api_models.GetAddressResp, error) {
	fName := "GetUserAddress"
	addr, err := db_main.GetUserAddress(map[string]interface{}{"uid": uid})
	if err != nil {
		return nil, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	if addr.Id <= 0 {
		return nil, nil
	}
	return &api_models.GetAddressResp{
		Id:       addr.Id,
		Province: addr.Province,
		City:     addr.City,
		District: addr.District,
		Address:  addr.Address,
		Name:     addr.Name,
		Mobile:   addr.Mobile,
	}, nil
}

func (s *Service) GetUserProfile(id int) (*models_main.UserProfile, error) {
	return db_main.GetUserProfileParam(map[string]interface{}{"uid": id})
}

func (s *Service) GetUserByNickName(nickname string, uid int) (int64, error) {
	return db_main.GetUserCount(map[string]interface{}{
		"nick_name": nickname,
		"id":        map[string]interface{}{"<>": uid},
	})
}

func (s *Service) CheckNicknameReview(uid int) (int64, error) {
	return db_main.CheckNicknameReview(uid)
}

func (s *Service) UpdateUser(columns []string, user *models_main.User) error {
	err := db_main.UpdateUser(columns, user)
	if err != nil {
		return fmt.Errorf("%s%s", util.Convert2(), err.Error())
	}
	return nil
}

func (s *Service) UpdateUserLoginInfo(user *models_main.User, loginPlatform int) error {
	fName := "UpdateUserLoginInfo"
	token, err := encrypt.TokenWebDesECBEncrypt()
	if err != nil {
		return fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	user.Token = token
	user.LastLogin = time.Now().In(time2.GetLocalLocation())
	user.LoginPlatform = loginPlatform
	user.TokenWeb = token

	userCol := []string{"last_login", "login_platform", "last_ip", "token", "token_web", "online_status"}
	//if loginPlatform > 0 { //0-Web 1-iOS 2-Android
	//	userCol = append(userCol, "token")
	//} else {
	//	user.TokenWeb = token
	//	userCol = append(userCol, "token_web")
	//}
	err = db_main.UpdateUser(userCol, user)
	if err != nil {
		return fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	return nil
}

func (s *Service) GetUserProfileByUid(uid int) (*models_main.UserProfile, error) {
	return db_main.GetUserProfileParam(map[string]interface{}{"uid": uid})
}

func (s *Service) EditUserInfo(user_col, profile_col []string, userApply *models_main.UserApply, user *models_main.User, profile *models_main.UserProfile) error {
	fName := "EditUserInfo"
	if len(user_col) <= 0 && len(profile_col) <= 0 && userApply.UserID < 0 {
		return nil
	}

	tx := s.DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	if err := tx.Error; err != nil {
		return fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}

	if len(user_col) > 0 {
		if err := db_main.UpdateUserByTransactions(tx, user_col, user); err != nil {
			tx.Rollback()
			return fmt.Errorf("%s%s", util.Convert(fName), err.Error())
		}
	}

	if userApply.UserID > 0 {
		if err := db_main.InsertUserApply(tx, userApply); err != nil {
			tx.Rollback()
			return fmt.Errorf("%s%s", util.Convert(fName), err.Error())
		}
	}

	if len(profile_col) > 0 {
		if err := db_main.UpdateProfileByTransactions(tx, profile_col, profile); err != nil {
			tx.Rollback()
			return fmt.Errorf("%s%s", util.Convert(fName), err.Error())
		}
	}

	if err := tx.Commit().Error; err != nil {
		return fmt.Errorf("%s %s", util.Convert(fName), err.Error())
	}
	cache.DelUserFullCache(user.Id)
	return nil
}

func (s *Service) GetUserProfitCount(uid, consumeType int) (int64, error) {
	return db_main.GetUserProfitCount(map[string]interface{}{
		"uid":          uid,
		"consume_type": consumeType,
		"type":         1,
	})
}

func (s *Service) GetLiveHistoryCount(uid int) (int64, error) {
	return db_live.GetLiveHistoryCount(map[string]interface{}{"anchorid": uid})
}

func (s *Service) GetLiveHistory(uid, page, size int) ([]*models_live.LiveHistory, error) {
	return db_live.GetLiveHistorysParam(map[string]interface{}{"anchorid": uid}, "start_time desc", page, size)
}

func (s *Service) GetManagedRooms(uid int) ([]*api_models.GetManagedRoomsResp, error) {
	fName := "GetManagedRooms"
	resp := make([]*api_models.GetManagedRoomsResp, 0)
	anchorIds, err := db_live.GetLiveRoomManagerForIds(map[string]interface{}{"mgrid": uid}, "anchorid")
	if err != nil {
		return nil, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}

	if len(anchorIds) <= 0 {
		return resp, nil
	}

	anchorMap, err := s.GetAnchors(0, anchorIds, "", 0, 0)
	if err != nil {
		return nil, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	anchors := make([]*api_models.Anchor, 0)
	for key := range anchorMap {
		anchors = append(anchors, anchorMap[key])
	}
	err = copier.Copy(&resp, &anchors)
	if err != nil {
		return nil, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}

	return resp, nil
}

func (s *Service) ForgetPwd(r *api_models.ForgetPwdReq) (string, error) {
	fName := "ForgetPwd"
	//布隆驗證手機號碼存在
	exists, err := global2.BloomExists(global2.BLOOM_MOBILE, r.Mobile)
	if err != nil {
		global2.Log.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	if !exists {
		return "该手机号尚未注册", fmt.Errorf("%s该手机号尚未注册", util.Convert(fName))
	}
	//验证码
	err = s.CheckCode(r.Mobile, r.Smscode)
	if err != nil {
		return err.Error(), fmt.Errorf("验证码%s%s", util.Convert(fName), err.Error())
	}
	//验证手机号
	user, err := mysql.GetUserParam(map[string]interface{}{"mobile": r.Mobile})
	if err != nil {
		return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	if user.Id <= 0 || user.Status == _const.ACCOUNT_DEACTIVED {
		return "该手机号尚未注册", fmt.Errorf("%s 该手机号尚未注册", util.Convert(fName))
	}
	password, err := encrypt.PwdDesECBEncrypt(user.Account, r.Pwd)
	if err != nil {
		return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	if util.CheckPwd(r.Pwd) {
		user.Password = password
		err = db_main.UpdateUser([]string{"password"}, user)
	} else {
		return "密码格式不符", fmt.Errorf("%s%s", util.Convert(fName), "密码格式不符")
	}
	if err != nil {
		return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	cache.DelUserLastToken(user.Id) //删掉这个last token，使快速登陆失效
	return "", nil
}

func (s *Service) ChangePwd(r *api_models.ChangePwdReq, user *models_main.User) (string, error) {
	fName := "ChangePwd"

	password, err := encrypt.PwdDesECBEncrypt(user.Account, r.Pwd)
	if err != nil {
		return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}

	//验证码
	err = s.CheckCode(user.Mobile, r.Smscode)
	if err != nil {
		return err.Error(), fmt.Errorf("验证码 %s %s", util.Convert(fName), err.Error())
	}
	if util.CheckPwd(r.Pwd) {
		user.Password = password
		err = db_main.UpdateUser([]string{"password"}, user)
	} else {
		return "密码格式不符", fmt.Errorf("%s%s", util.Convert(fName), "密码格式不符")
	}

	if err != nil {
		return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	cache.DelUserLastToken(user.Id) //删掉这个last token，使快速登陆失效
	return "", nil
}

func (s *Service) AddBank(r *api_models.AddBankReq, user *models_main.User) (string, error) {
	fName := "AddBank"

	existbank, err := db_main.GetUserBankParam(map[string]interface{}{"uid": user.Id, "deleted": 0, "card": r.Card})
	if err != nil {
		return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	if existbank.Id > 0 {
		return "卡号已存在", fmt.Errorf("%s 卡号已存在", util.Convert(fName))
	}
	cTime := time.Now()
	bank := &models_main.UserBank{
		Uid:        user.Id,
		Bank:       r.Bank,
		Name:       r.Name,
		Card:       r.Card,
		Idcard:     r.IdCard,
		Deleted:    0,
		CreateTime: cTime,
		UpdateTime: cTime,
	}
	err = db_main.InsertUserBank(nil, bank)
	if err != nil {
		return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	return "", nil
}

func (s *Service) GetBanks(user *models_main.User) ([]*models_main.UserBank, error) {
	fName := "GetBanks"

	banks, err := db_main.GetUserBanksParam(map[string]interface{}{"uid": user.Id, "deleted": 0}, "", 0, 0)
	if err != nil {
		return nil, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	return banks, nil
}

func (s *Service) DelBank(id int, user *models_main.User) (string, error) {
	fName := "DelBank"
	bank, err := db_main.GetUserBankParam(map[string]interface{}{"uid": user.Id, "id": id})
	if err != nil {
		return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	if bank.Id <= 0 {
		return "银行卡不存在", fmt.Errorf("%s 银行卡不存在", util.Convert(fName))
	}
	bank.Deleted = 1
	bank.UpdateTime = time.Now()
	err = db_main.UpdateUserBank(nil, []string{"deleted", "update_time"}, bank)
	if err != nil {
		return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	return "", nil
}

func (s *Service) ChangeMobile(r *api_models.ChangeMobileReq, user *models_main.User) (string, error) {
	fName := "ChangeMobile"
	exuser, err := mysql.GetUserParam(map[string]interface{}{"mobile": r.NewMobile})
	if err != nil {
		return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	if exuser.Id > 0 {
		return "新手机号已存在", fmt.Errorf("%s 新手机号已存在", util.Convert(fName))
	}
	// 验证码测试模式
	if r.NewSmscode == _const.POWER_CODE && cache.GetConfigPub().PowerMode == 1 {
		user.Mobile = r.NewMobile
		err = db_main.UpdateUser([]string{"mobile"}, user)
		if err != nil {
			return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
		}
		return "", nil
	}
	oriSmsCode, err := db_main.GetSmscodeParam(map[string]interface{}{
		"mobile":      user.Mobile,
		"code":        r.OriSmsCode,
		"status":      1,
		"create_time": map[string]interface{}{">": time.Now().Add(time.Duration(-30) * time.Minute)},
	}, "create_time desc")
	if err != nil {
		return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	if oriSmsCode.Id <= 0 {
		return "当前手机号验证码有误或已过期", fmt.Errorf("%s 当前手机号验证码有误或已过期", util.Convert(fName))
	}
	newSmsCode, err := db_main.GetSmscodeParam(map[string]interface{}{
		"mobile":      r.NewMobile,
		"code":        r.NewSmscode,
		"status":      0,
		"create_time": map[string]interface{}{">": time.Now().Add(time.Duration(-30) * time.Minute)},
	}, "create_time desc")
	if err != nil {
		return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	if newSmsCode.Id <= 0 {
		return "新手机号验证码有误或已过期", fmt.Errorf("%s 新手机号验证码有误或已过期", util.Convert(fName))
	}
	user.Mobile = r.NewMobile
	err = db_main.UpdateUser([]string{"mobile"}, user)
	if err != nil {
		return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	newSmsCode.Status = 1
	err = db_main.UpdateSmscode(newSmsCode)
	if err != nil {
		fmt.Printf("%s %v %s\n", util.Convert(fName), newSmsCode, err.Error())
	}
	return "", nil
}

func (s *Service) ChangeQqAndWx(r *api_models.ChangeQqAndWxReq, user *models_main.User) (string, error) {
	fName := "ChangeQqAndWx"
	if r.Smscode != _const.POWER_CODE && cache.GetConfigPub().PowerMode == 1 {
		smscode, err := db_main.GetSmscodeParam(map[string]interface{}{
			"mobile":      user.Account,
			"code":        r.Smscode,
			"status":      0,
			"create_time": map[string]interface{}{">": time.Now().Add(time.Duration(-30) * time.Minute)},
		}, "create_time desc")
		if err != nil {
			return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
		}
		if smscode.Id <= 0 {
			return "当前手机号验证码有误或已过期", fmt.Errorf("%s 当前手机号验证码有误或已过期", util.Convert(fName))
		}
		smscode.Status = 1
		err = db_main.UpdateSmscode(smscode)
		if err != nil {
			fmt.Printf("%s %s\n", util.Convert(fName), err.Error())
		}
	}
	//user.QqUnionid = r.QqUnionid
	//user.WxUnionid = r.WxUnionid
	err := db_main.UpdateUser([]string{"wx_unionid", "qq_unionid"}, user)
	if err != nil {
		return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	return "", nil
}

func (s *Service) ChangePayPwd(r *api_models.ChangePayPwdReq, user *models_main.User) (string, error) {
	fName := "ChangePayPwd"

	password, err := encrypt.PwdDesECBEncrypt(user.Account, r.Pwd)
	if err != nil {
		return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}

	//验证码
	err = s.CheckCode(user.Mobile, r.Smscode)
	if err != nil {
		return err.Error(), fmt.Errorf("验证码 %s %s", util.Convert(fName), err.Error())
	}

	user.PayPassword = password
	err = db_main.UpdateUser([]string{"pay_password"}, user)
	if err != nil {
		return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	return "", nil
}

func (s *Service) GetFans(r *api_models.GetFansReq, user *models_main.User) ([]*api_models.GetFansResp, error) {
	fName := "GetFans"
	list, err := db_main.GetAnchorFanssParam(map[string]interface{}{"anchorid": user.Id}, "create_time desc", r.Page, r.Size)
	if err != nil {
		return nil, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	tmpIds := make([]int, 0)
	for i := range list {
		tmpIds = append(tmpIds, list[i].Fansid)
	}
	anchorMap, err := s.GetAnchors(0, tmpIds, "", 0, 0)
	if err != nil {
		return nil, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	resp := make([]*api_models.GetFansResp, 0)
	err = copier.Copy(&resp, &list)
	if err != nil {
		return nil, err
	}
	attentids := cache.GetUserAttentAnchorIds(user.Id)
	for i := range resp {
		if _, ok := anchorMap[resp[i].Fansid]; ok {
			resp[i].Fan = anchorMap[resp[i].Fansid]
		}
		for j := range attentids {
			if resp[i].Fansid == attentids[j] {
				resp[i].Fan.Isattent = 1
			}
		}
	}
	return resp, nil
}

func (s *Service) SaveAddress(r *api_models.AddAddressReq, user *models_main.User) (string, error) {
	fName := "SaveAddress"
	//编辑
	if r.Id > 0 {
		address, err := db_main.GetUserAddressParam(map[string]interface{}{"id": r.Id})
		if err != nil {
			return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
		}
		if address == nil {
			return "编辑地址不存在", fmt.Errorf("%s 编辑地址不存在", util.Convert(fName))
		}
		address.Province = r.Province
		address.City = r.City
		address.District = r.District
		address.Address = r.Address
		address.Name = r.Name
		address.Mobile = r.Mobile
		err = db_main.UpdateUserAddress([]string{
			"province",
			"city",
			"district",
			"address",
			"name",
			"mobile",
		}, address)
		if err != nil {
			return "编辑地址失败", fmt.Errorf("%s 编辑地址失败", util.Convert(fName))
		}
	}

	existAddress, err := db_main.GetUserAddressParam(map[string]interface{}{"uid": user.Id})
	if err != nil {
		return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	if existAddress.Id > 0 {
		return "收貨地址已存在", fmt.Errorf("%s 收貨地址已存在", util.Convert(fName))
	}
	address := &models_main.UserAddress{
		Id:        0,
		Uid:       user.Id,
		Province:  r.Province,
		City:      r.City,
		District:  r.District,
		Address:   r.Address,
		Name:      r.Name,
		Mobile:    r.Mobile,
		IsDefault: 1,
	}
	err = db_main.InsertUserAddress(nil, address)
	if err != nil {
		return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	return "", nil
}

func GetUserAddress(user *models_main.User) (*api_models.GetAddressResp, error) {
	fName := "GetUserAddress"
	addr, err := db_main.GetUserAddressParam(map[string]interface{}{"uid": user.Id})
	if err != nil {
		return nil, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	return &api_models.GetAddressResp{
		Id:       addr.Id,
		Province: addr.Province,
		City:     addr.City,
		District: addr.District,
		Address:  addr.Address,
		Name:     addr.Name,
		Mobile:   addr.Mobile,
	}, nil
}

func (s *Service) VerifyToken(token string, uid int, platform int) (bool, error) {
	fName := "VerifyToken"
	msg, err := db_main.VerifyToken(token, uid, platform)
	if err != nil || !msg {
		return false, fmt.Errorf("%s%s", util.Convert(fName), err)
	}
	return true, nil
}

func (s *Service) GetUserAsset(user *models_main.User) (*api_models.UserAsset, error) {
	fName := "GetUserAsset"

	userAsset, err := db_main.GetUserAsset(user)
	if err != nil {
		return nil, fmt.Errorf("%s%s", util.Convert(fName), err)
	}
	return userAsset, nil
}

func (s *Service) CheckAnchorStatus(user *models_main.User) (*api_models.AnchorStatus, error) {
	anchorStatus := new(api_models.AnchorStatus)

	anchorStatus.IsAnchor = user.IsAnchor
	live, _ := cache.GetAnchorLive(user.Id)

	if live.Liveid > 0 {
		if live.Status != cache.EndLive {
			anchorStatus.ISLive = 1
		}
	}

	return anchorStatus, nil
}

func (s *Service) UserBackPack(uid int) ([]*api_models.UserBackPackRsp, error) {
	//换到/models_live/user_backpack方法获取
	var userBackPackRsp []*api_models.UserBackPackRsp
	list, err := db_main.GetUserBackpacksParam(map[string]interface{}{"uid": uid, "used": 0}, "", 0, 0)
	if err != nil {
		return nil, err
	}
	tm := time.Now().Unix()
	for _, v := range list {
		flag := false
		for _, l := range userBackPackRsp {
			if l.Gid == v.Gid && v.ExpTime >= tm && v.EffTime < tm {
				l.Num++
				flag = true
			}
		}
		if !flag {
			userBackPackRsp = append(userBackPackRsp, &api_models.UserBackPackRsp{Gid: v.Gid, Num: 1, PropsType: int(v.Type)})
		}

	}
	return userBackPackRsp, nil
}

// 驗證手機號存在
func (s *Service) CheckUserIsExistByMobile(mobile string) bool {
	// 驗證手機號存在
	exists, err := global2.BloomExists(global2.BLOOM_MOBILE, mobile)
	if err != nil {
		global2.Log.Errorf("bloom varify error : %s", err.Error())
	}
	if !exists {
		return false
	}

	count, _ := db_main.GetUserCount(echo.Map{"mobile": mobile})
	if count == 0 {
		return false
	}
	return true
}

func (s *Service) GetUserByCtx(c echo.Context) (*models_main.User, error) {
	user := &models_main.User{}
	uid, ok := c.Get("uid").(int)
	if !ok {
		return user, errors.New("assertion fail")
	}
	exists, err := global2.BloomExists(global2.BLOOM_ID, cast.ToString(uid))
	if err != nil || !exists {
		global2.Log.Errorf("GetUserByCtx err:%v,uid:%d,clientIp:%s", err, uid, c.RealIP())
		return user, errors.New("user not exist")
	}
	user, err = cache.GetUserFullInfo(uid)
	if err != nil {
		return user, errors.New("GetUserFullInfo error")
	}
	//user, err := mysql.GetUserParam(map[string]interface{}{"id": uid})
	//if err != nil {
	//	return nil, err
	//}
	if user.Id <= 0 {
		return user, errors.New("user not exist")
	}
	return user, nil
}

func (s *Service) GetInviteInfo(uid uint) (*api_models.GetInviteInfoResp, error) {
	agent, err := db_main.GetAgentByUid(uid)
	if err != nil {
		return nil, err
	}
	invitedUser, err := db_main.GetInvitedUser(uid)
	if err != nil {
		return nil, err
	}
	return &api_models.GetInviteInfoResp{
		InviteCode:       cache.GetConfigPub().H5Domain + "register?code=" + string(encrypt.Base34(uid)),
		Diamond:          agent.Diamond,          //页面上应除以100
		WithDrawnDiamond: agent.WithdrawnDiamond, //已领取钻石数量
		InvitedUserList:  invitedUser,
	}, nil
}

func (s *Service) ReceiveInvitationReward(user *models_main.User) error {
	agent, err := db_main.GetAgentByUid(uint(user.Id))
	if err != nil {
		return err
	}
	tx := global2.GetX().Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()
	if err := tx.Error; err != nil {
		return fmt.Errorf("%s %s", util.Convert2(), err.Error())
	}
	if agent.Id < 0 || agent.Diamond == 0 { // 钻石数目
		tx.Rollback()
		return errors.New("快去邀请好友吧")
	}

	addAmount := agent.Diamond
	user.Diamond += int(addAmount) //更新当前请求用户的钻石数量
	if err := db_main.UpdateUserByTransactions(tx, []string{"diamond"}, user); err != nil {
		return err
	}
	err = db_main.InsertInviteByTx(tx, &models_main.InviteRecord{
		Uid:     user.Id,
		Content: fmt.Sprintf("通过邀请活动,获得了%d龙钻", addAmount/100),
	})
	if err != nil {
		return err
	}
	agent.WithdrawnDiamond += addAmount //已领取钻石数目
	agent.Diamond = 0                   //钻石数目修改成0
	if err := db_main.UpdateAgentByTransactions(tx, agent); err != nil {
		return err
	}

	//// 收支明细
	if err := addUserInviteProfit(tx,
		user.NickName,
		user.Id,
		int(addAmount)); err != nil {
		tx.Rollback()
		return err
	}

	if err := tx.Commit().Error; err != nil {
		tx.Rollback()
		return fmt.Errorf("%s %s", util.Convert2(), err.Error())
	}
	return nil
}

// 拉新添加收益记录
func addUserInviteProfit(tx *gorm.DB, inviteUser string, uid int, diamond int) error {
	var (
		fName     = "6addUserProfit9"
		profitLog = make([]*models_main.UserProfit, 1)
	)

	// 拉新领取收益
	userProfit := &models_main.UserProfit{
		Uid:         uid,     //查询条件根据登录人的id匹配
		CoinCount:   diamond, //鹰钻或金坷拉数量
		FUid:        0,       //系统赠送（新人注册成功可以领取xx钻石）
		ConsumeType: _const.PROFIT_INVITE_REGISTER,
		Type:        _const.TYPE_PROFIT, //赚钱记录

		Content: fmt.Sprintf("%s 邀请好友注册，领取收益:%d龙钻",
			inviteUser, diamond/100, //只有在显示自然语言的时候才除100
		),
		Resid:      0,
		Count:      diamond, //鹰钻或克拉数量（单位分）
		CreateTime: time.Now(),
		CoinType:   2,
		OrderNo:    util.GenOrderId("IR", 1),
		Liveid:     0,
	}
	global2.Log.Debugf("%s写收益记录来源方:%v", fName, userProfit)

	profitLog = []*models_main.UserProfit{
		userProfit,
	}

	err := db_main.InsertUserProfitByTransactions(tx, profitLog)
	if err != nil {
		global2.Log.Error("%s推广人拉新收益记录写入失败:%v", fName, profitLog)
	}
	return err
}

// 新增用户反馈意见
func (s *Service) SendFeedback(userID int, r *api_models.UserFeedbackReq) error {

	err := db_main.InsertFeedback(userID, r)
	if err != nil {
		return err
	}
	return nil
}

// 检查绑定6T账号状态
func (s *Service) CheckBindAccount(user *models_main.User) (*api_models.CheckBindAccountResp, error) {
	fName := "CheckBindAccount"

	existbindAccount, err := db_main.GetUserBindAccountParam(map[string]interface{}{"uid": user.Id, "deleted": 0})

	if err != nil {
		return &api_models.CheckBindAccountResp{}, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}

	var isBind bool
	if existbindAccount.Uid > 0 {
		isBind = true
	}
	return &api_models.CheckBindAccountResp{
		IsBind:  isBind,
		Account: existbindAccount.Account,
		Uid:     existbindAccount.Uid,
	}, nil
}

// 绑定6T账号
func (s *Service) AddBindAccount(r *api_models.BindAccountReq, user *models_main.User) (string, error) {
	fName := "AddBindAccount"

	count := cache.GetUserBindAccountCountCache(user)
	if count >= 5 {
		return "绑定频繁，请稍后再试", fmt.Errorf("%s", util.Convert(fName))
	}
	cache.SetUserBindAccountCountCache(user)

	existbindAccount, err := db_main.GetUserBindAccountParam(map[string]interface{}{"account": r.Account, "deleted": 0})
	if err != nil {
		return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}

	if existbindAccount.Uid > 0 {
		return "该账号已绑定，如有疑问请咨询客服", fmt.Errorf("%s", util.Convert(fName))
	}

	existbindUser, err := db_main.GetUserBindAccountParam(map[string]interface{}{"uid": user.Id})
	if err != nil {
		return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}

	if existbindUser.Uid > 0 {
		if existbindUser.Deleted == 0 {
			return "该账号已绑定，如有疑问请咨询客服", fmt.Errorf("%s", util.Convert(fName))
		}

		bindAccount := &models_main.UserBindingAccount{
			Uid:            user.Id,
			Account:        r.Account,
			CreateTime:     time.Now(),
			Deleted:        0,
			FirstCheckTime: time.Now(),
		}
		err = db_main.UpdateUserBindAccount(nil, []string{"deleted", "uid", "account", "create_time", "first_check_time"}, bindAccount)
		if err != nil {
			return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
		}
	} else {
		cTime := time.Now()
		bindAccount := &models_main.UserBindingAccount{
			Uid:        user.Id,
			Deleted:    0,
			CreateTime: cTime,
			Account:    r.Account,
			Status:     0,
		}
		err = db_main.InsertUserBindAccount(nil, bindAccount)
		if err != nil {
			return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
		}
	}

	return "", nil
}

// 解绑6T账号
func (s *Service) UnbindAccount(user *models_main.User) (string, error) {
	fName := "UnbindAccount"

	existbindAccount, err := db_main.GetUserBindAccountParam(map[string]interface{}{"uid": user.Id, "deleted": 0})
	if err != nil {
		return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}

	if existbindAccount.Uid == 0 {
		return "该账号未绑定任何账户，如有疑问请咨询客服", fmt.Errorf("%s 用户绑定账号不存在", util.Convert(fName))
	}

	bindAccount := &models_main.UserBindingAccount{
		Uid:     user.Id,
		Deleted: 1,
	}
	err = db_main.UpdateUserBindAccount(nil, []string{"deleted", "uid"}, bindAccount)
	if err != nil {
		return "", fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	return "", nil
}
